package com.zmn.mcc.services.impl.staff;

import com.zmn.anole.dubbo.interfaces.AnoleRemoteService;
import com.zmn.base.common.data.dubbo.interfaces.company.CompanyListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto.LoginStaff;
import com.zmn.common.dto.StatusDTO;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.mcc.business.interfaces.staff.ip.StaffIpInfoBService;
import com.zmn.mcc.cache.StaffCache;
import com.zmn.mcc.common.constant.StaffChangeLogConsts;
import com.zmn.mcc.common.constant.StaffConsts;
import com.zmn.mcc.common.dictionary.StaffDict;
import com.zmn.mcc.common.dto.exception.MccException;
import com.zmn.mcc.common.dto.staff.StaffIdAndRealNameDRO;
import com.zmn.mcc.model.dto.staff.McStaffSimpleDTO;
import com.zmn.mcc.model.entity.dept.McDept;
import com.zmn.mcc.model.entity.log.IpInfo;
import com.zmn.mcc.model.entity.staff.*;
import com.zmn.mcc.model.entity.staff.staffchangelog.StaffChangeLog;
import com.zmn.mcc.model.vo.McStaffVO;
import com.zmn.mcc.persistence.interfaces.staff.StaffDao;
import com.zmn.mcc.services.interfaces.dept.DeptService;
import com.zmn.mcc.services.interfaces.staff.StaffService;
import com.zmn.mcc.services.interfaces.staff.staffchangelog.StaffChangeLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.assertj.core.util.Lists;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author heguanghua
 * @since 2020/04/14 15:14
 */
@Slf4j
@Service
public class StaffServiceImpl implements StaffService {

    @Resource
    private StaffDao staffDao;

    @Resource
    private StaffChangeLogService staffChangeLogService;

    @Resource
    private StaffCache staffCache;

    @Resource
    private DeptService deptService;

    @Resource
    StaffIpInfoBService staffIpInfoBService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private AnoleRemoteService anoleRemoteService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CompanyListRemoteService baseCompanyListRemoteService;

    private PasswordService passwordService = new PasswordService();

    @Override
    public Integer countByDTalkIdAndNotStaffId(Integer staffId, String dTalkId) {
        return staffDao.countByDTalkIdAndNotStaffId(staffId, dTalkId);
    }

    @Override
    public Integer countBystaffNumberAndNotStaffId(Integer staffId, String staffNumber) {
        if (Objects.isNull(staffNumber)) {
            log.error("工号不能为空");
            return 0;
        }
        return staffDao.countBystaffNumberAndNotStaffId(staffId, staffNumber);
    }

    @Override
    public McStaff findByKey(Integer staffId) {
        return staffDao.findByKey(staffId);
    }

    @Override
    public McStaff findForLogin(McStaffQuery query) {
        return staffDao.findForLogin(query);
    }

    @Override
    public McStaff findByDTalkId(String dUserid) {
        if (Objects.isNull(dUserid)) {
            log.error("钉钉userid不能为空");
            return null;
        }
        return staffDao.findByDTalkId(dUserid);
    }

    @Override
    public Boolean findStaffNameExists(String staffName, Integer staffId) {
        McStaff staff = new McStaff();
        staff.setStaffName(staffName);
        staff.setStaffId(staffId);
        return this.findStaffNameExists(staff);
    }

    @Override
    public Boolean findStaffNameExists(McStaff staff) {
        return staffDao.findStaffNameExists(staff) > 0;
    }

    @Override
    public Boolean findMobileExists(String mobile, Integer staffId) {
        McStaff staff = new McStaff();
        staff.setMobile(mobile);
        staff.setStaffId(staffId);
        return this.findMobileExists(staff);
    }

    @Override
    public Boolean findMobileExists(McStaff staff) {
        return staffDao.findMobileExists(staff) > 0;
    }

    @Override
    public Boolean findMailExists(String mail, Integer staffId) {
        McStaff staff = new McStaff();
        staff.setMail(mail);
        staff.setStaffId(staffId);
        return this.findMailExists(staff);
    }

    @Override
    public Boolean findMailExists(McStaff staff) {
        return staffDao.findMailExists(staff) > 0;
    }

    @Override
    public Boolean findStaffNumberExists(McStaff staff) {
        return staffDao.findStaffNumberExists(staff) > 0;
    }

    @Override
    public String findMaxStaffName() {

        return staffDao.findMaxStaffName();
    }

    @Override
    public List<McStaff> listPageByQuery(McStaffQuery query) {
        Integer count = this.countByQuery(query);
        query.setTotalCount(count);
        return count == 0 ? new ArrayList<>(0) : staffDao.listPageByQuery(query);
    }

    @Override
    public List<McStaffVO> listPageInfoByQuery(McStaffQuery query) {

        if (NumberUtil.isNotNullOrZero(query.getDeptId())) {
            List<Integer> deptIds = new ArrayList<>();
            deptIds.add(query.getDeptId());
            listSubDeptIds(deptIds, deptIds, GlobalConsts.YES);
            query.setDeptIds(deptIds);
        }
        Integer count = this.countPageInfoByQuery(query);
        query.setTotalCount(count);
        return count == 0 ? new ArrayList<>(0) : staffDao.listPageInfoByQuery(query);
    }

    @Override
    public List<McStaff> listByQuery(McStaffQuery query) {
        return staffDao.listByQuery(query);
    }

    @Override
    public List<McStaff> listSimpleByKeyword(String keyword, Integer status) {
        McStaffQuery query = new McStaffQuery();
        query.setKeyword(keyword);
        query.setStatus(status);
        return this.listSimpleByQuery(query);
    }

    @Override
    public List<McStaff> listByMoblieAndDTalkIdIsNotNull(String mobile) {
        if (StringUtil.isBlank(mobile)) {
            log.error("根据电话查询员工电话不能为空：" + mobile);
            return null;
        }
        return staffDao.listByMoblieAndDTalkIdIsNotNull(mobile);
    }

    @Override
    public List<McStaff> listSimpleByRoleId(Integer roleId, Integer status) {
        McStaffQuery query = new McStaffQuery();
        query.setRoleId(roleId);
        query.setStatus(status);
        return this.listSimpleByQuery(query);
    }

    @Override
    public List<McStaff> listSimpleByRoleIds(List<Integer> roleIds, Integer status) {
        McStaffQuery query = new McStaffQuery();
        query.setRoleIds(roleIds);
        query.setStatus(status);
        return this.listSimpleByQuery(query);
    }

    @Override
    public List<McStaffSimpleDTO> listStaffByRoleIdsIncludeRoleId(List<Integer> roleIds, Integer status) {
        McStaffQuery query = new McStaffQuery();
        query.setRoleIds(roleIds);
        query.setStatus(status);
        return staffDao.listStaffByRoleIdsIncludeRoleId(query);
    }

    @Override
    public List<McStaff> listSimpleByDeptIds(List<Integer> deptIds, Integer status) {
        McStaffQuery query = new McStaffQuery();
        query.setDeptIds(deptIds);
        query.setStatus(status);
        return this.listSimpleByQuery(query);
    }

    @Override
    public List<McStaff> listSimpleByStaffIds(List<Integer> staffIds, Integer status) {
        McStaffQuery query = new McStaffQuery();
        query.setStaffIds(staffIds);
        query.setStatus(status);
        return this.listSimpleByQuery(query);
    }

    @Override
    public List<Integer> listStaffIdByDeptIds(List<Integer> deptIds) {

        if (CollectionUtil.isNullOrEmpty(deptIds)) {
            return null;
        }
        this.listSubDeptIds(deptIds, deptIds, GlobalConsts.YES);
        return staffDao.listStaffIdByDeptIds(deptIds);
    }

    @Override
    public List<McStaff> listBsStaffInfo(List<Integer> bsUserIds) {
        return staffDao.listBsStaffInfo(bsUserIds);
    }


    @Override
    public List<McStaff> listSimpleByQuery(McStaffQuery query) {
        if (NumberUtil.isNullOrZero(query.getNumber())) {
            query.setNumber(300);
        }
        return staffDao.listSimpleByQuery(query);
    }

    @Override
    @Cacheable(cacheNames = "redis1h", key = "'staff:onlinestaffvt:status:'+#p0+':staffStatusList:'+#p1+':number:'+#p2", unless = "#result == null || #result.size() <= 0")
    public List<VtDTO> listVtByStatus(Integer status, List<Integer> staffStatusList, Integer number) {
        return staffDao.listVtByStatus(status, staffStatusList, number);
    }


    @Override
    public List<McStaff> listSubStaffByQuery(McStaffQuery query) {
        if (NumberUtil.isNullOrZero(query.getNumber())) {
            query.setNumber(100);
        }
        return staffDao.listSubStaffByQuery(query);
    }

    /**
     * 描述: 根据员工id集合、部门id、状态，查询员工id与姓名
     *
     * @param staffIdList 员工id集合
     * @param deptId      部门id
     * @param status      状态：1 停止 2 正常/启用
     * @return List<StaffIdAndRealNameDRO>
     * @author xujie
     * @since 2021/04/28
     **/
    @Override
    public List<StaffIdAndRealNameDRO> listStaffIdByStaffIdListAndDeptIdAndStatus(List<Integer> staffIdList, Integer deptId, Integer status) {

        if (staffIdList == null || staffIdList.size() == 0 || deptId == null || status == null) {
            return new ArrayList<>();
        }
        return staffDao.listStaffIdByStaffIdListAndDeptIdAndStatus(staffIdList, deptId, status);
    }

    /**
     * 描述: 根据员工id集合查询钉钉Id
     *
     * @param staffIdList 员工id集合
     * @return List<StaffIdAndDTalkId>
     * @author xujie
     * @since 2021/04/28
     **/
    @Override
    public List<StaffIdAndDTalkId> listStaffIdAndDTalkIdByStaffIdList(List<Integer> staffIdList) {

        if (staffIdList == null || staffIdList.size() == 0) {
            return new ArrayList<>();
        }
        return staffDao.listStaffIdAndDTalkIdByStaffIdList(staffIdList);
    }

    /**
     * 描述: 根据员工id集合查询部门Id
     *
     * @param staffIdList 员工id集合
     * @return List<StaffIdAndDeptId>
     * @author xujie
     * @since 2021/05/28
     **/
    @Override
    public List<StaffIdAndDeptId> listStaffIdAndDeptIdByStaffIdList(List<Integer> staffIdList) {

        if (staffIdList == null || staffIdList.size() == 0) {
            return new ArrayList<>();
        }
        return staffDao.listStaffIdAndDeptIdByStaffIdList(staffIdList);
    }

    @Override
    public Integer countByQuery(McStaffQuery query) {
        return staffDao.countByQuery(query);
    }

    @Override
    public Integer countPageInfoByQuery(McStaffQuery query) {
        return staffDao.countPageInfoByQuery(query);
    }

    @Override
    public Integer updateByKey(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());

        return staffDao.updateByKey(staff);
    }

    @Override
    public Integer updateDTalkId(McStaff staff) {
        return staffDao.updateDTalkId(staff);
    }

    @Override
    public Integer updateBsStaff(McStaff staff) {
        // 根据组织架构查询公司  如果有多个则取第一个
//        CompanyDIO baseCompanyQuery = new CompanyDIO();
//        baseCompanyQuery.setOrgId(staff.getOrgId());
//        ResponseDTO<AMISListData<CompanyDRO>> responseDTO = baseCompanyListRemoteService.listPageCompanyDROByQuery(baseCompanyQuery);
//        List<CompanyDRO> baseCompanies = responseDTO.isSuccess() ? responseDTO.getData().getItems() : new ArrayList<>(1);
//        if (CollectionUtil.isNotNullOrEmpty(baseCompanies)) {
//            staff.setCompanyId(baseCompanies.get(0).getCompanyId());
//        }
        return staffDao.updateBsStaff(staff);
    }

    @Override
    public Integer updatePassword(Integer staffId, String password, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setPassword(password);
        staff.setUpdater(updater);
        return this.updatePassword(staff);
    }

    @Override
    public Integer updatePassword(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        staff.setSalt(passwordService.generateSalt());
        staff.setPassword(passwordService.generatePassword(staff.getPassword(), staff.getSalt()));
        staff.setInitPwd(GlobalConsts.NO);

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updatePassword(staff);
    }

    @Override
    public Integer updateInitPasswordByKey(String password, LoginStaff loginStaff, Integer staffId) {
        String updater = "system";
        if (Objects.nonNull(loginStaff) && StringUtil.isNotBlank(loginStaff.getRealName())) {
            updater = loginStaff.getRealName();
        }

        // 删除员工缓存
        staffCache.deleteStaff(staffId);
        return staffDao.updateInitPasswordByKey(password, updater, staffId);
    }

    @Override
    public Integer updateLastLoginTime(Integer staffId) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        return this.updateLastLoginTime(staff);
    }

    @Override
    public Integer updateLastLoginTime(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        if (staff.getLastLoginTime() == null) {
            staff.setLastLoginTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateLastLoginTime(staff);
    }

    @Override
    public Integer updateWhitelist(Integer staffId, Integer whitelist, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setWhitelist(whitelist);
        staff.setUpdater(updater);
        return this.updateWhitelist(staff);
    }

    @Override
    public Integer updateWhitelist(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateWhitelist(staff);
    }

    @Override
    public Integer updatePermitSelf(Integer staffId, Integer permitSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setPermitSelf(permitSelf);
        staff.setUpdater(updater);
        return this.updatePermitSelf(staff);
    }

    @Override
    public Integer updatePermitSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updatePermitSelf(staff);
    }

    @Override
    public Integer updateDpermitSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitSelf(staff);
    }

    @Override
    public Integer updateDpermitOrgSelf(Integer staffId, Integer dpermitOrgSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitOrgSelf(dpermitOrgSelf);
        staff.setUpdater(updater);
        return this.updateDpermitOrgSelf(staff);
    }

    @Override
    public Integer updateDpermitOrgSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitOrgSelf(staff);
    }

    @Override
    public Integer updateDpermitDeptSelf(Integer staffId, Integer dpermitDeptSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitDeptSelf(dpermitDeptSelf);
        staff.setUpdater(updater);
        return this.updateDpermitDeptSelf(staff);
    }

    @Override
    public Integer updateDpermitDeptSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitDeptSelf(staff);
    }

    @Override
    public Integer updateDpermitAreaSelf(Integer staffId, Integer dpermitAreaSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitAreaSelf(dpermitAreaSelf);
        staff.setUpdater(updater);
        return this.updateDpermitAreaSelf(staff);
    }

    @Override
    public Integer updateDpermitAreaSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitAreaSelf(staff);
    }

    @Override
    public Integer updateDpermitCooperationSelf(Integer staffId, Integer dpermitChannelSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitCooperationSelf(dpermitChannelSelf);
        staff.setUpdater(updater);
        return this.updateDpermitCooperationSelf(staff);
    }

    @Override
    public Integer updateDpermitCooperationSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitCooperationSelf(staff);
    }

    @Override
    public Integer updateDpermitCubeSelf(Integer staffId, Integer dpermitCubeSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitCubeSelf(dpermitCubeSelf);
        staff.setUpdater(updater);
        return this.updateDpermitCubeSelf(staff);
    }

    @Override
    public Integer updateDpermitCubeSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitCubeSelf(staff);
    }

    @Override
    public Integer updateDpermitMeasureSelf(Integer staffId, Integer dpermitMeasureSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitMeasureSelf(dpermitMeasureSelf);
        staff.setUpdater(updater);
        return this.updateDpermitMeasureSelf(staff);
    }

    @Override
    public Integer updateDpermitMeasureSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitMeasureSelf(staff);
    }

    @Override
    public Integer updateDpermitProductSelf(Integer staffId, Integer dpermitProductSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitProductSelf(dpermitProductSelf);
        staff.setUpdater(updater);
        return this.updateDpermitProductSelf(staff);
    }

    @Override
    public Integer updateDpermitPromotionSelf(Integer staffId, Integer dpermitAccountSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitPromotionSelf(dpermitAccountSelf);
        staff.setUpdater(updater);
        return this.updateDpermitPromotionSelf(staff);
    }

    @Override
    public Integer updateDpermitPromotionSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitAccountSelf(staff);
    }

    @Override
    public Integer updateDpermitChannelSelf(Integer staffId, Integer dpermitNewChannelSelf, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setDpermitChannelSelf(dpermitNewChannelSelf);
        staff.setUpdater(updater);
        return this.updateDpermitChannelSelf(staff);
    }

    @Override
    public Integer updateDpermitChannelSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitChannelSelf(staff);
    }

    @Override
    public Integer updateDpermitProductSelf(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateDpermitProductSelf(staff);
    }

    @Override
    public Integer updateDtalkIdByStaffId(Integer staffId, String dTalkId, String realName) {
        if (Objects.isNull(staffId)) {
            log.error("根据主键修改员工ID不能为空：" + staffId);
            return null;
        }

        // 删除员工缓存
        staffCache.deleteStaff(staffId);
        return staffDao.updateDtalkIdByStaffId(staffId, dTalkId, realName);
    }

    @Override
    public Integer updateStatus(Integer staffId, Integer status, String updater) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setStatus(status);
        staff.setUpdater(updater);
        return this.updateStatus(staff);
    }

    @Override
    public Integer updateStatus(McStaff staff) {
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }

        // 删除员工缓存
        staffCache.deleteStaff(staff.getStaffId());
        return staffDao.updateByKey(staff);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateStatusBatch(List<Integer> staffIds, Integer status, LoginStaff staffLogin, String ip) {
        StatusDTO dto = new StatusDTO();
        dto.setIds(staffIds);
        dto.setStatus(status.intValue());
        dto.setUpdater(staffLogin.getRealName());

        IpInfo ipInfo = staffIpInfoBService.locationByIP(ip);
        String abutmenterCity = null;
        if (Objects.nonNull(ipInfo)) {
            abutmenterCity = ipInfo.getProvince() + "-" + ipInfo.getCity();
        }
        for (Integer staffId : staffIds) {
            // 删除员工缓存
            staffCache.deleteStaff(staffId);
            // 记录日志
            McStaff staff = staffCache.getStaff(staffId);
            if (!Objects.equals(status, staff.getStatus())) {
                StaffChangeLog staffChangeLog = StaffChangeLog.builder()
                        .staffId(staff.getStaffId())
                        .beforContent(StaffDict.getStatusTypeName(staff.getStatus()))
                        .afterContent(StaffDict.getStatusTypeName(status))
                        .abutmenterId(staffLogin.getStaffId())
                        .abutmenter(staffLogin.getRealName())
                        .abutmenterDeptId(staffLogin.getDeptId() + "")
                        .abutmenterDeptName(staffLogin.getDeptName())
                        .changeType(StaffChangeLogConsts.CHANGE_TYPE_STATUS)
                        .createTime(DateUtil.getNow())
                        .ip(ip)
                        .abutmenterCity(abutmenterCity)
                        .build();
                staffChangeLogService.insert(staffChangeLog);
            }
        }
        return updateStatusBatch(dto);
    }

    @Override
    public Integer updateStatusBatch(StatusDTO dto) {
        if (dto.getUpdateTime() == null) {
            dto.setUpdateTime(DateUtil.getNow());
        }
        return staffDao.updateStatusBatch(dto);
    }

    @Override
    public Integer updateSort(Integer staffId, Integer sort) {
        McStaff staff = new McStaff();
        staff.setStaffId(staffId);
        staff.setSort(sort);
        return this.updateSort(staff);
    }

    @Override
    public Integer updateSort(McStaff staff) {
        return staffDao.updateSort(staff);
    }

    @Override
    public void leaveStaff(Integer staffId, LoginStaff staffLogin, String ip) throws MccException {
        if (NumberUtil.isNullOrZero(staffId)) {
            log.error("staffId null error, staffId:{}", staffId);
            throw new MccException("员工ID不能为空");
        }

        McStaff staff = staffDao.findByKey(staffId);
        if (Objects.isNull(staff)) {
            log.error("staff null error, staff:{}", staff);
            throw new MccException("员工不存在");
        }

        // 禁用员工账号，将员工设置为离职
        staff.setStatus(GlobalConsts.NO);
        staff.setStaffStatus(StaffConsts.STAFF_STATUS_LEAVE);
        staff.setUpdater(staffLogin.getRealName());
        staff.setUpdateTime(DateUtil.getNow());
        staffDao.updateByKey(staff);

        IpInfo ipInfo = staffIpInfoBService.locationByIP(ip);
        String abutmenterCity = null;
        if (Objects.nonNull(ipInfo)) {
            abutmenterCity = ipInfo.getProvince() + "-" + ipInfo.getCity();
        }
        StaffChangeLog staffChangeLog = StaffChangeLog.builder()
                .staffId(staff.getStaffId())
                .beforContent("-")
                .afterContent("状态从正常修改为离职")
                .abutmenterId(staffLogin.getStaffId())
                .abutmenter(staffLogin.getRealName())
                .abutmenterDeptId(staffLogin.getDeptId() + "")
                .abutmenterDeptName(staffLogin.getDeptName())
                .changeType(StaffChangeLogConsts.CHANGE_TYPE_LEAVE)
                .createTime(DateUtil.getNow())
                .ip(ip)
                .abutmenterCity(abutmenterCity)
                .build();
        staffChangeLogService.insert(staffChangeLog);
    }

    @Override
    public void reinstatementStaff(Integer staffId, LoginStaff staffLogin, String ip) throws MccException {
        if (NumberUtil.isNullOrZero(staffId)) {
            log.error("staffId null error, staffId:{}", staffId);
            throw new MccException("员工ID不能为空");
        }

        McStaff staff = staffDao.findByKey(staffId);
        if (Objects.isNull(staff)) {
            log.error("staff null error, staff:{}", staff);
            throw new MccException("员工不存在");
        }

        // 禁用员工账号，将员工设置为离职
        staff.setStatus(GlobalConsts.YES);
        staff.setStaffStatus(StaffConsts.STAFF_STATUS_NORMAL);
        staff.setUpdater(staffLogin.getRealName());
        staff.setUpdateTime(DateUtil.getNow());
        staffDao.updateByKey(staff);

        IpInfo ipInfo = staffIpInfoBService.locationByIP(ip);
        String abutmenterCity = null;
        if (Objects.nonNull(ipInfo)) {
            abutmenterCity = ipInfo.getProvince() + "-" + ipInfo.getCity();
        }
        StaffChangeLog staffChangeLog = StaffChangeLog.builder()
                .staffId(staff.getStaffId())
                .beforContent("-")
                .afterContent("状态从离职修改为正式")
                .abutmenterId(staffLogin.getStaffId())
                .abutmenter(staffLogin.getRealName())
                .abutmenterDeptId(staffLogin.getDeptId() + "")
                .abutmenterDeptName(staffLogin.getDeptName())
                .changeType(StaffChangeLogConsts.CHANGE_TYPE_REINSTATEMENT)
                .createTime(DateUtil.getNow())
                .ip(ip)
                .abutmenterCity(abutmenterCity)
                .build();
        staffChangeLogService.insert(staffChangeLog);
    }


    @Override
    public Integer insert(McStaff staff) {
        if (NumberUtil.isNullOrZero(staff.getOrgTop())) {
            staff.setOrgTop(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(staff.getType())) {
            staff.setType(StaffConsts.STAFF_ROLE_ORDINARY_TYPE);
        }
        staff.setSort(100);
        staff.setStatus(GlobalDict.STATUS_ENABLE);
        if (staff.getUpdateTime() == null) {
            staff.setUpdateTime(DateUtil.getNow());
        }
        staff.setCreater(staff.getUpdater());
        staff.setCreateTime(staff.getUpdateTime());
        return staffDao.insert(staff);
    }


    @Override
    public Integer deleteByKey(Integer staffId) {
        return staffDao.deleteByKey(staffId);
    }

    @Override
    public Integer insertBsStaff(McStaff staff) {
        return staffDao.insertBsStaff(staff);
    }

    @Override
    public Integer countByBsUserIdAndNotStaffId(Integer staffId, Integer bsUserId) {
        return staffDao.countByBsUserIdAndNotStaffId(staffId, bsUserId);
    }

    @Override
    public Integer updateBsUserIdByStaffId(Integer staffId, Integer bsUserId, String realName) {
        if (Objects.isNull(staffId)) {
            log.error("根据主键修改员工ID不能为空：" + staffId);
            return null;
        }

        // 删除员工缓存
        staffCache.deleteStaff(staffId);

        return staffDao.updateBsUserIdByStaffId(staffId, bsUserId, realName);
    }

    @Override
    public List<StaffIdAndBsUserId> listStaffIdAndBsUserId() {

        return staffDao.listStaffIdAndBsUserId();
    }

    @Override
    public McStaff findStaffByDingTalkId(String dingTalkId) {

        return staffDao.findStaffByDingTalkId(dingTalkId);
    }

    @Override
    public void updateWorkTime(McStaff staff) {
        staffDao.updateWorkTime(staff);
    }

    @Override
    public McStaff findByBsUserId(Integer bsUserId) {
        if (Objects.isNull(bsUserId)) {
            log.warn("北森用户ID为空");
            return null;
        }
        return staffDao.findByBsUserId(bsUserId);
    }

    @Override
    public String getDTalkIdByMail(String mail) {
        return staffDao.getDTalkIdByMail(mail);
    }

    @Override
    public void updateDeptNameByDeptId(Integer deptId, String deptName) {
        if (Objects.isNull(deptId) || Objects.isNull(deptName)) {
            return;
        }
        staffDao.updateDeptNameByDeptId(deptId, deptName);
    }

    /**
     * 描述: 递归查询下级部门
     */
    private void listSubDeptIds(List<Integer> resultDeptIds, List<Integer> deptIds, Integer status) {

        if (CollectionUtils.isEmpty(deptIds)) {
            return;
        }
        List<McDept> items = deptService.listByParentIds(deptIds, status);
        if (CollectionUtils.isEmpty(items)) {
            return;
        }
        List<Integer> currentDeptIds = items.stream().map(McDept::getDeptId).collect(Collectors.toList());
        resultDeptIds.addAll(currentDeptIds);
        listSubDeptIds(resultDeptIds, currentDeptIds, status);
    }

    @Override
    public List<McStaff> listSimpleStaffByDeptIds(Integer deptOneId, List<Integer> deptTwoIds) {
        return staffDao.listSimpleStaffByDeptIds(deptOneId, deptTwoIds);
    }

    @Override
    public List<McStaff> listByLeaderIds(List<Integer> staffIds) {
        if (CollectionUtil.isNullOrEmpty(staffIds)) {
            return Collections.emptyList();
        }

        return staffDao.listByLeaderIds(staffIds);
    }


    @Override
    public List<McStaff> listByMobile(String mobile) {
        ResponseDTO<String> encrypt = anoleRemoteService.encrypt(mobile);
        if (encrypt.isSuccess()) {
            return staffDao.listByMobile(encrypt.getData());
        } else {
            return Lists.emptyList();
        }
    }
}
